<?php
/**
 * db_mssql.php
 *
 * mssql数据库驱动
 * @package core
 * @author wang <wang@fvzone.com>
 * @copyright  Copyright (c) 2010 Fire vision Software Studio
 * @link http://www.fvzone.com
 * @license New BSD License.{@link http://www.opensource.org/licenses/bsd-license.php}
 * @version $Id:db_mssql.php 1.3 2011-11-13 20:35:00Z wang $
 * @since 1.0
 */

defined('IN_WORK') or exit('Authorization error');


class db_mssql extends Work {

    /**
     * 单例模式实例化对象
     *
     * @var object
     */
    public static $instance;

    /**
     * 数据库连接ID
     *
     * @var object
     */
    public $db_link;

    /**
     * 事务处理开启状态
     *
     * @var boolean
     */
    public $Transactions;


    /**
     * 构造函数
     *
     * @access public
     * @param array $params 数据库连接参数,如主机名,数据库用户名,密码等
     * @return boolean
     */
    public function __construct($params = array()) {

        //检测数据库连接参数是否完整
        if (!$params['host'] || !$params['username'] || !$params['password'] || !$params['dbname']) {
            throwException('Database Server HostName or UserName or Password or DatabaseName error in the config file!');
        }

        $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' :':';
        $params['host'] = $params['host'] . ($params['port'] ? $port_delimiter . $params['port'] :'');

        @ini_set('mssql.charset', 'UTF-8');
        @ini_set('mssql.textlimit', 2147483647);
        @ini_set('mssql.textsize', 2147483647);

        $this->db_link = @mssql_connect($params['host'], $params['username'], $params['password']);

        if ($this->db_link && $params['dbname'] != '') {
            if (!mssql_select_db($params['dbname'], $this->db_link)) {
                mssql_close($this->db_link);
                return false;
            }
        }

        if (!$this->db_link) {
            throwException($params['driver'] . ' Server connect fail! <br/>Error Message:' . $this->error());
        }

        return true;
    }

    /**
     * 执行SQL语句
     *
     * SQL语句执行函数
     * @access public
     * @param string $sql SQL语句内容
     * @return mixed
     */
    public function query($sql) {

        //参数分析
        if (!$sql) {
            return false;
        }

        $result = mssql_query($sql, $this->db_link);

        //日志操作,当调试模式开启时将所执行过的SQL写入SQL跟踪日志文件,便于DBA进行数据库优化.若调试模式关闭,当SQL语句执行错误时写入日志文件
        if (DEBUG === false) {
            if ($result == false) {
                //获取当前运行的controller及action名称
                $controller_id        = Work::getControllerName();
                $action_id            = Work::getActionName();

                Log::write('[' . $controller_id . '][' . $action_id . '] SQL execute failed :' . $sql . ' Error Message:' . $this->error());
                Controller::alert('Database SQL execute failed!');
            }
        } else {
            //获取当前运行的controller及action名称
            $controller_id        = Work::getControllerName();
            $action_id            = Work::getActionName();
            $sql_log_file        = APP_DIR . 'logs/' . 'SQL_' . date('Y_m_d', $_SERVER['REQUEST_TIME']) . ' . log';

            if ($result == true) {
                Log::write('[' . $controller_id . '][' . $action_id . ']:' . $sql, 'Normal', $sql_log_file);
            } else {
                throwException('[' . $controller_id . '][' . $action_id . '] SQL execute failed :' . $sql . '<br/>Error Message:' . $this->error() . '<br/>Error SQL:' . $sql);
            }
        }

        return $result;
    }

    /**
     * 获取数据库错误描述信息
     *
     * @access public
     * @return string
     */
    public function error() {

        return mssql_get_last_message();
    }

    /**
     * 通过一个SQL语句获取一行信息(字段型)
     *
     * @access public
     * @param string $sql SQL语句内容
     * @return mixed
     */
    public function fetch_row($sql) {

        //参数分析
        if (!$sql) {
            return false;
        }

        $result = $this->query($sql);

        if (!$result) {
            return false;
        }

        $myrow     = mssql_fetch_assoc($result);
        mssql_free_result($result);

        return $myrow;
    }

    /**
     * 通过一个SQL语句获取全部信息(字段型)
     *
     * @access public
     * @param string $sql SQL语句
     * @return array
     */
    public function get_array($sql) {

        //参数分析
        if (!$sql) {
            return false;
        }

        $result = $this->query($sql);

        if (!$result) {
            return false;
        }

        $myrow     = array();
        while ($row = mssql_fetch_assoc($result)) {
            $myrow[] = $row;
        }
        mssql_free_result($result);

        return $myrow;
    }

    /**
     * 获取insert_id
     *
     * @access public
     * @return int
     */
    public function insert_id(){

        $result_id = mssql_query('SELECT SCOPE_IDENTITY()', $this->db_link);

        if ($result_id) {
            if ($row = mssql_fetch_assoc($result_id)) {
                mssql_free_result($result_id);
                return $row['computed'];
            }
            mssql_free_result($result_id);
        }

        return false;
    }

    /**
     * 开启事务处理
     *
     * @access public
     * @return boolean
     */
    public function startTrans() {

        if($this->Transactions == false){
            if ($this->query('BEGIN TRANSACTION')) {
                $this->Transactions = true;
            }
        }

        return true;
    }

    /**
     * 提交事务处理
     *
     * @access public
     * @return boolean
     */
    public function commit() {

        if ($this->Transactions == true) {
            if ($this->query('COMMIT TRANSACTION')) {
                $this->Transactions = false;
            } else {
                //获取当前运行的controller及action名称
                $controller_id        = Work::getControllerName();
                $action_id            = Work::getActionName();

                if (DEBUG === true) {
                    throwException('[' . $controller_id . '][' . $action_id . '] SQL Commit failed <br/>Error Message:' . $this->error());
                } else {
                    Log::write('[' . $controller_id . '][' . $action_id . '] SQL Commit failed. Error Message:' . $this->error());
                    Controller::alert('Database SQL execute failed!');
                }
            }
        }

        return true;
    }

    /**
     * 事务回滚
     *
     * @access public
     * @return boolean
     */
    public function rollback() {

        if ($this->Transactions == true) {
            if ($this->query('ROLLBACK TRANSACTION')) {
                $this->Transactions = false;
            } else {
                //获取当前运行的controller及action名称
                $controller_id        = Work::getControllerName();
                $action_id            = Work::getActionName();

                if (DEBUG === true) {
                    throwException('[' . $controller_id . '][' . $action_id . '] SQL RollBack failed <br/>Error Message:' . $this->error());
                } else {
                    Log::write('[' . $controller_id . '][' . $action_id . '] SQL RollBack failed. Error Message:' . $this->error());
                    Controller::alert('Database SQL execute failed!');
                }
            }
        }

        return true;
    }

    /**
     * 转义字符
     *
     * @access public
     * @param string $string 待转义的字符串
     * @return string
     */
    public function escape_string($string) {

        //参数分析
        if (!$string) {
            return  false;
        }

        return addslashes($string);
    }

    /**
     * 析构函数
     *
     * @access public
     * @return void
     */
    public function __destruct() {

        if($this->db_link == true) {
            @mssql_close($this->db_link);
        }
    }

    /**
     * 单例模式
     *
     * @access public
     * @param array $params 数据库连接参数,如数据库服务器名,用户名,密码等
     * @return object
     */
    public static function getInstance($params)
    {
        if (!self::$instance) {
            self::$instance = new self($params);
        }
        return self::$instance;
    }
}